﻿using System;
using System.Xml ;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace MVCFramework.View
{
    public partial class GeneralUserControlView : UserControl ,IView 
    {
        public GeneralUserControlView()
        {
            InitializeComponent();
        }

        private IModel _model;
        private IPresenter _presenter;

        #region IView Members

        private Id<IView> _id;
        public Id<IView> Id
        {
            get
            {
                if (_id.IsEmpty) return "UserControl";
                return _id;
            }
            set
            {
                _id = value;
            }
        }

        public void AddFilter(MVCFramework.Models.Filters.IFilter filter)
        {
            throw new NotImplementedException();

            FilteredViewState state = null;
            state.AddFilter(filter);
            this.ViewState = state;
            Update();
        }

        public event EventHandler<EventArgs> OnStateChanged;

        protected ViewStateAbstract _viewState;
        public ViewStateAbstract ViewState
        {
            set
            {
                _viewState = value;

                if (OnStateChanged != null)
                    OnStateChanged(this, new EventArgs());
            }
            get
            {
                return _viewState;
            }
        }

        #endregion

        void IView.Update()
        {
            Console.WriteLine("Updating " + this.GetType().ToString());
            if (ViewState != null) ViewState.DispalyView();
        }

        public void SetViewState(Type viewState)
        {
            ViewState = Activator.CreateInstance(viewState) as ViewStateAbstract;
            ViewState.Model = this._model;
        }

        public void SetViewState(Type viewState, Type[] argTypes, object[] args, string[] argNames)
        {

            object _object = BuildingBasicDomain.DefaultFactoryBase.CreateInstance(viewState, argTypes, args, argNames);
            if (_object != null)
                ViewState = _object as ViewStateAbstract;
            else throw new MVCFramework.ModelExeption("View failed to set ist's state to " + viewState.Name);
            ViewState.Model = this._model;

        }

        public void setUpControl(IModel  model, IPresenter  presenter)
        {
            this._model = model;
            this._presenter = presenter;
            presenter.AddView(this);
            this.ViewState = new TreeListViewState();

            this.ViewState.Model = model;
            this.ViewState.ModelVisitor = new TreeListVisistor(treeView1);
            
        }
        
        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            object _object = e.Node.Tag;

            
            if (_object is ISelectable)
            {
            //    ((ISelectable)_object).IsSelected = !((ISelectable)_object).IsSelected;
              //  UpdateNode(e.Node ,((ISelectable)_object).IsSelected);
            //    _presenter.NotifyViews<IView>
            //        (
          //         delegate(IView view) { if (view.Id != this._id)return true; return false; }
          //          );

                System.Collections.ArrayList list = new System.Collections.ArrayList();
                list.Add(_object);
                MVCFramework.Presenter.ActionEventArgs args = new MVCFramework.Presenter.ActionEventArgs(list);
                ((MVCFramework .IViewActionListener )_presenter).MouseDownHandler(this, args);
                this.ContextMenu = new ContextMenu();

                ContextMenu.MenuItems.Add(new MenuItem("DeleteElement",OnClickMenu));
            }

        }
        public void OnClickMenu(object sender, EventArgs args)
        {
            //this._presenter .RequestRemoval <IModelData >
        }
        public void UpdateNode(TreeNode node ,bool IsSelected )
        {
            if (IsSelected) { node.BackColor = Color.Yellow; }
            if (!IsSelected) node.BackColor = Color.White ;
        }
    }

    public class TreeListViewState : MVCFramework.View.ViewStateAbstract
    {
        


        public override void DispalyView()
        {
            ModelVisitor.Visit(this.Model);
        }

    }

    public class TreeListFilteredViewState : FilteredViewState
    {
    /// <summary>
    /// 
    /// </summary>
    public TreeListFilteredViewState(ViewState state, MVCFramework.Models.Filters.IFilter filter) : base(state, filter) { }


        public override void DispalyView()
        {
            ModelVisitor.Visit(this.Model);
        }
    }

    public class TreeListVisistor : IVisitor
    {
        #region IVisitor Members
      //  System.Collections.Hashtable selectionHash;

        public TreeView treeview;

        public TreeListVisistor(TreeView treeview)
        {
            this.treeview = treeview;
        }

        public virtual void Visit(object element)
        {
            if (element is IModel)
                Visit(element as IModel);
            else VisitNode(element);
        }

      //  public MVCFramework.Models.IdManager<ICountable> idmanager = new MVCFramework.Models.IdManager<ICountable>();

        private void Visit(IModel model)
        {
            treeview.Nodes.Clear();
     
           // this.model = model;

            foreach (IModelData data in model)
                Visit(data);
        }

        private void VisitNode(object element)
        {
            if (element == null) return;
            //int id  =idmanager.Register(element);
            TreeNode node = new TreeNode(element.ToString());
            node.Tag = element;

            if (element is ISelectable)
                if (((ISelectable)element).IsSelected)
                { node.BackColor  = Color .Yellow  ; }

            treeview.Nodes.Add(node);

        }
        #endregion
    }
}
